<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="JvSdv" id="JvSdv"><span data-lake-id="udc246c20" id="udc246c20">典型回答</span></h1>
  <p data-lake-id="u9ca3fdfd" id="u9ca3fdfd"><br></p>
  <p data-lake-id="u705f1f13" id="u705f1f13"><span data-lake-id="u87439bb2" id="u87439bb2">一般这个问题，主要是因为在SpringMVC的应用中，过滤器和拦截器都是用来对请求进行预处理、过滤、拦截的，所以经常会放在一起比较。不过他们其实还有一些区别的。</span></p>
  <p data-lake-id="u67504af0" id="u67504af0"><span data-lake-id="ue3065c7c" id="ue3065c7c">​</span><br></p>
  <p data-lake-id="u0f923db9" id="u0f923db9"><span data-lake-id="ua83bfada" id="ua83bfada">他们的主要区别在于作用和生效的位置不同，过滤器是在请求进入Servlet容器之前拦截请求并对请求进行处理，而拦截器是在请求进入Servlet容器之后，但在进入Controller之前拦截请求并对请求进行处理，也可以在响应返回客户端之前，拦截响应并对响应进行处理。</span></p>
  <p data-lake-id="uae175681" id="uae175681"><span data-lake-id="udb691652" id="udb691652">​</span><br></p>
  <p data-lake-id="uff88e9c0" id="uff88e9c0"><strong><span data-lake-id="u72d7ff98" id="u72d7ff98">在Tomcat中，一次请求会先进入到Tomcat容器，然后经过Filter的处理，处理通过之后才会进入到Servlet容器，进入到Servlet容器之后，才会在Servlet执行的前后执行Intercepter。</span></strong></p>
  <p data-lake-id="u9c6b3096" id="u9c6b3096"><span data-lake-id="ub5dcd1ec" id="ub5dcd1ec">​</span><br></p>
  <p data-lake-id="u60c28126" id="u60c28126"><img src="https://cdn.nlark.com/yuque/0/2023/png/5378072/1681637359987-23b72280-ad3d-448a-b701-18f83101941f.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_30%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"></p>
  <p data-lake-id="ud2013a7e" id="ud2013a7e"><span data-lake-id="u1623ed95" id="u1623ed95">过滤器在请求进入Servlet容器之前拦截请求并对请求进行处理，比如对请求进行安全验证、日志记录等，之后将请求转发给对应的Servlet进行处理。</span><strong><span data-lake-id="ua7b2b3e5" id="ua7b2b3e5">过滤器是基于Java Servlet规范实现的，可以通过配置web.xml文件进行实现。</span></strong></p>
  <p data-lake-id="u2f1d55e2" id="u2f1d55e2"><span data-lake-id="u06c83185" id="u06c83185">​</span><br></p>
  <p data-lake-id="u80aa2bbe" id="u80aa2bbe"><span data-lake-id="u25c6ca72" id="u25c6ca72">拦截器是在请求进入Servlet容器之后，拦截请求并对请求进行处理，也可以在响应返回客户端之前，拦截响应并对响应进行处理。拦截器可以对请求进行更加精细的控制，例如进行AOP、权限控制、事务管理等操作。</span><strong><span data-lake-id="u196e7a54" id="u196e7a54">拦截器是基于Spring框架实现的，可以通过定义拦截器类实现。</span></strong></p>
  <p data-lake-id="u1417fd05" id="u1417fd05"><span data-lake-id="u1df6fa1e" id="u1df6fa1e">​</span><br></p>
  <p data-lake-id="ubd3f2868" id="ubd3f2868"><span data-lake-id="u6ea877d5" id="u6ea877d5">​</span><br></p>
  <h1 data-lake-id="NgIrF" id="NgIrF"><span data-lake-id="ufe972f77" id="ufe972f77">扩展知识</span></h1>
  <p data-lake-id="ud413cec7" id="ud413cec7"><br></p>
  <h2 data-lake-id="iYV73" id="iYV73"><span data-lake-id="u05974a32" id="u05974a32">代码实现</span></h2>
  <p data-lake-id="uebec320a" id="uebec320a"><br></p>
  <p data-lake-id="u5ef76d29" id="u5ef76d29"><span data-lake-id="u8d382233" id="u8d382233">定义一个过滤器，需要实现javax.servlet.Filter接口：</span></p>
  <p data-lake-id="ua68f6fb2" id="ua68f6fb2"><span data-lake-id="uc54aa087" id="uc54aa087">​</span><br></p>
  <pre lang="java"><code>
public class LoginFilter implements Filter {
    public void init(FilterConfig config) throws ServletException {
        // 初始化
    }
 
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        // 登录验证和处理
        chain.doFilter(req, resp);
    }
 
    public void destroy() {
        // 销毁
    }
}
</code></pre>
  <p data-lake-id="uad92fcdd" id="uad92fcdd"><br></p>
  <p data-lake-id="u1ba8b743" id="u1ba8b743"><span data-lake-id="ud04c9cdf" id="ud04c9cdf">并且需要在web.xml文件中把他配置上:</span></p>
  <p data-lake-id="u100a75e3" id="u100a75e3"><span data-lake-id="u89a6780d" id="u89a6780d">​</span><br></p>
  <pre lang="java"><code>
&lt;filter&gt;
    &lt;filter-name&gt;LoginFilter&lt;/filter-name&gt;
    &lt;filter-class&gt;com.hollis.LoginFilter&lt;/filter-class&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
    &lt;filter-name&gt;LoginFilter&lt;/filter-name&gt;
    &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;
</code></pre>
  <p data-lake-id="ue9214d1e" id="ue9214d1e"><br></p>
  <p data-lake-id="u9afed037" id="u9afed037"><span data-lake-id="u02868b6c" id="u02868b6c">或者通过注解也可以。</span></p>
  <p data-lake-id="ub3d71712" id="ub3d71712"><span data-lake-id="u8a87f986" id="u8a87f986">​</span><br></p>
  <p data-lake-id="u47fd0cfc" id="u47fd0cfc"><span data-lake-id="ud0c699c1" id="ud0c699c1">在 LoginFilter上添加@WebFilter注解，并在启动类上增加@ServletComponentScan("com.hollis.filter.LoginFilter")注解。也可替代xml文件中的配置。</span></p>
  <p data-lake-id="ucd7b8ba6" id="ucd7b8ba6"><br></p>
  <p data-lake-id="u9e22cdf5" id="u9e22cdf5"><span data-lake-id="uacf6ba15" id="uacf6ba15">想要定义一个拦截器，需要实现org.springframework.web.servlet.HandlerInterceptor接口：</span></p>
  <p data-lake-id="uc4a77c0b" id="uc4a77c0b"><span data-lake-id="u909e3123" id="u909e3123">​</span><br></p>
  <pre lang="java"><code>
@Component
public class LoginInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
       // 登录验证和处理
        return true;
    }
 
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 后处理
    }
 
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 完成处理
    }
}
</code></pre>
  <p data-lake-id="ufd7b94cc" id="ufd7b94cc"><span data-lake-id="uead2835d" id="uead2835d">​</span><br></p>
  <p data-lake-id="u04274f1d" id="u04274f1d"><span data-lake-id="u81d4bb2d" id="u81d4bb2d">并且在SpringMVC中进行配置：</span></p>
  <p data-lake-id="u882e981b" id="u882e981b"><span data-lake-id="u7eeafcc2" id="u7eeafcc2">​</span><br></p>
  <pre lang="java"><code>
&lt;mvc:interceptors&gt;
    &lt;mvc:interceptor&gt;
        &lt;mvc:mapping path="/api/*"/&gt;
        &lt;bean class="com.hollis.LoginInterceptor"/&gt;
    &lt;/mvc:interceptor&gt;
&lt;/mvc:interceptors&gt;
</code></pre>
  <p data-lake-id="u229b4b61" id="u229b4b61"><span data-lake-id="u9eb774a1" id="u9eb774a1">​</span><br></p>
  <p data-lake-id="u09ff3f86" id="u09ff3f86"><span data-lake-id="u3deb8b9c" id="u3deb8b9c">或者</span></p>
  <p data-lake-id="u91d32f70" id="u91d32f70"><span data-lake-id="ue8add35b" id="ue8add35b">​</span><br></p>
  <pre lang="java"><code>
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/api/*");
    }
}

</code></pre>
 </body>
</html>